import { HttpHeaders } from '@angular/common/http';
import { Inject, Injectable } from '@angular/core';
import { CookieService } from 'ngx-cookie-service';
import { Observable } from 'rxjs';
import { ApiResult } from '../models/api.result';
import { TokenResponse } from '../models/token-response';
import { HttpService } from './http.service';
import { LoginInfoService } from './login-info.service';
import { error } from '@ant-design/icons-angular';
import { Router } from '@angular/router';
import { ApiService } from './api.service';
import { AppSettingsService } from './app-settings.service';
import { REDIRECT_ADDR, REST_URL } from '../app.component';

export class Foo {
  constructor(
    public id: number,
    public name: string) { }
}

@Injectable({
  providedIn: 'root'
})
export class AppService {
//TEST
  public clientId!: string;
//  public clientId = 'messaging-client';
 

  constructor(
    private _http: HttpService, private cookieService: CookieService,
    private _loginInfoService: LoginInfoService,
    private _router: Router,
    private _api: ApiService,
    private _appSettings: AppSettingsService,
    @Inject(REST_URL) private baseUrl: string,
    @Inject(REDIRECT_ADDR) private redirectUri: string) {
      const settings = _appSettings.getSettings();
      this.clientId = settings.clientId;
     }

  retrieveToken(code: string) {
    const params = new URLSearchParams();
    params.append('grant_type', 'authorization_code');
    params.append('client_id', this.clientId);
    params.append('redirect_uri', this.redirectUri);
    params.append('code', code);
    console.log(`ready to retrive token with ${this.redirectUri}, ${code}`);

    const headers = new HttpHeaders({'Content-type': 'application/x-www-form-urlencoded; charset=utf-8',
       'Authorization': "Basic " + btoa(this.clientId + ":123456")});

    const resp = this._http.postWithHeaders<TokenResponse>(this.baseUrl + 'oauth2/token', params.toString(), headers);
    console.log(`Post returned ${resp} with type ` + typeof (resp));
    resp.subscribe({
      next: resp => {
        console.log(`oauth token get response ${resp.access_token}`);
        this.saveRefreshToken(resp);
        this.saveToken(resp);
        
        this._loginInfoService.isLoggedIn.next(true);
      },
      error: () => {
        console.log(`'subscribe error ${error}`);
      }
    });
  }

  refreshToken() {
    const refreshToken = this.cookieService.get('refresh_token');
    if (refreshToken == null || refreshToken === '') {
      return;
    }

    const params = new URLSearchParams();
    params.append('grant_type', 'refresh_token');
    params.append('refresh_token', refreshToken);

    const headers = new HttpHeaders({
      'Content-type': 'application/x-www-form-urlencoded; charset=utf-8',
      'Authorization': "Basic " + btoa(this.clientId + ":123456")
    });

    const resp = this._http.postWithHeaders<TokenResponse>(this.baseUrl + 'oauth2/token', params.toString(), headers);
    console.log(`refresh token returned ${JSON.stringify(resp)}`);
    if (resp == null) {
      return;
    }

    resp.subscribe({
      next: resp => {
        console.log(`refresh token get response ${resp.access_token}`);
        
        const expireDate = new Date().getTime() + (1000 * resp.expires_in);
        this.cookieService.set("access_token", resp.access_token, expireDate);
      },
      error: () => {
        console.log(`'refresh token error ${error}`);
      }
    });
  }

  saveRefreshToken(token: TokenResponse) {
    this.cookieService.set('refresh_token', token.refresh_token);
  }

  saveToken(token: TokenResponse) {
    console.log(`token expires in ${token.expires_in} seconds`);
    const expireDate = new Date().getTime() + (1000 * token.expires_in);
    this.cookieService.set("access_token", token.access_token, expireDate);
    //   this.cookieService.set("id_token", token.id_token, expireDate);
    console.log('Obtained Access token');
    this._loginInfoService.isLoggedIn.next(true);
    window.location.href = this.redirectUri;
  }

  getResource(resourceUrl: string): Observable<ApiResult<string>> {
    const token = this.cookieService.get('access_token');
    const headers = new HttpHeaders({ 'Content-type': 'application/x-www-form-urlencoded', 'Authorization': 'Bearer ' + token });
    console.log(`get resource with token ${token}`);
    return this._http.getWithHeaders<ApiResult<string>>(resourceUrl, headers);
  }

  checkCredentials(): boolean {
    const result = this.cookieService.check('access_token');
    if (result) {
      console.log('check Credentials true, notify isLoggedIn');
      this._loginInfoService.isLoggedIn.next(true);
    }

    return result;
  }

  removeToken() {
    this.cookieService.delete('access_token');
    this.cookieService.delete('id_token');
  }


  logout() {
    this.cookieService.delete('access_token');
    this.cookieService.delete('JSESSIONID');
    console.log(`deleted cookies, redirect to home`);

    // this._api.logout().subscribe((resp) => {
    //   console.log(`logout returned ${resp}`);
    // });
    // this._loginInfoService.isLoggedIn.next(false);

    // const logoutUrl = 'http://localhost:4200';
    // window.location.href = logoutUrl;
    
    const logoutURL = this.baseUrl + "logout?post_logout_redirect_uri=" + this.redirectUri;
    console.log(`Logout to ${logoutURL}`);
    window.location.href = logoutURL;
    this._loginInfoService.isLoggedIn.next(false);


    // const logoutURL = "http://localhost:20110/connect/logout?id_token_hint=" + token
    //   + "&post_logout_redirect_uri=" + this.redirectUri;


    // this._loginInfoService.isLoggedIn.next(false);
    // console.log(`ready to logout to ${logoutURL}`);
    // window.location.href = logoutURL;
  }
}
